#include "MacMessage.hpp"

using namespace BFT::messages;

MacMessage::MacMessage(uint32_t _tag, uint32_t _size, uint32_t _sender)
	: VerifiedMessageBase::VerifiedMessageBase(_tag, _size, computeAuthenticationSize())
{
	sender = _sender;
	
	int bytes_size;
	boost::shared_ptr<char> bytes =  getBytes(bytes_size);
	
	unsigned int offset = getTotalSize() - getAuthenticationSize();
	
	//write the sender
	*(uint32_t*)(bytes.get()+offset) = htonl(sender);
}

MacMessage::MacMessage(boost::shared_ptr<char> _bytes, int _bytes_size)
	: VerifiedMessageBase::VerifiedMessageBase(_bytes, _bytes_size)
{	
	unsigned int offset = getTotalSize() - getAuthenticationSize();
	
	//read the sender
	sender = ntohl(*(uint32_t*)(_bytes.get()+offset));
	offset += SENDER_SIZE;
	
	if (offset != getTotalSize() - actualAuthenticationSize())
	{
		fprintf(stderr, "trying to build a MacMessage from invalid bytes\n");
//		fprintf(stderr, "initial offset: %d, token size: %d, final offset: %d, _bytes_size %d, authentication size %d")
		exit(102);
	}
}

int MacMessage::computeAuthenticationSize()
{
	return actualAuthenticationSize() + SENDER_SIZE;
}

int MacMessage::actualAuthenticationSize()
{
	return MacBytes::size();
}

boost::shared_ptr<MacBytes> MacMessage::getMacBytes()
{	
	boost::shared_ptr<char> dst ( (char*)malloc (MacBytes::size()));
	memcpy( (void*)dst.get(),  //copy in this locetion
		(const void *)(getBytes().get() + getTotalSize() - actualAuthenticationSize()), //from this location
		actualAuthenticationSize()); ///this number of bytes
	boost::shared_ptr<MacBytes> ret (new MacBytes(dst));
	return ret;		
}

void MacMessage::setMacBytes(boost::shared_ptr<MacBytes> _mb)
{
	memcpy( (void *)(getBytes().get() + getTotalSize() - actualAuthenticationSize()), //copy in this location
		(const void*)_mb.get()->getBytes().get(),  //from in this locetion
		actualAuthenticationSize()); ///this number of bytes
}
